package com.scs.application.modules.cfg.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.scs.application.core.consts.Const;
import com.scs.application.core.exception.BusinessException;
import com.scs.application.core.query.QueryContext;
import com.scs.application.core.service.BaseServiceImpl;
import com.scs.application.core.service.IBaseFileService;
import com.scs.application.core.utils.FileUtils;
import com.scs.application.core.utils.StringUtils;
import com.scs.application.modules.cfg.entity.Parameter;
import com.scs.application.modules.cfg.mapper.ParameterMapper;
import com.scs.application.modules.cfg.service.ParameterService;
import com.scs.application.modules.cfg.utils.ParameterUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description:参数的文件管理
 */
@Slf4j
@Service
public class FileParameterServiceImpl extends BaseServiceImpl<ParameterMapper, Parameter> implements ParameterService,  IBaseFileService<Parameter, Parameter> {

    @Override
    public void refreshCache() {

        log.info("==============加载系统参数开始==============");

        List<Parameter> parameters = new ArrayList<>();
        try{
            parameters = this.list();
        }catch (Exception e){
            logger.error("刷新缓存时获取配置参数失败",e);
        }
        for (Parameter parameter : parameters) {
            ParameterUtils.put(parameter.getParamKey(), parameter.getValue());
        }
        log.info("==============加载系统参数完成==============");

    }

    @Override
    public boolean removeCascadeById(Serializable id) {
        List<Parameter> parameters = list();
        for (Parameter parameter : parameters) {
            if (id.equals(parameter.getId())) {
                FileUtils.deleteFile(Const.DATA_VIEW_PARAMETER_SRC + parameter.getParamKey() + ".json");
                break;
            }
        }
        return true;
    }

    @Override
    public Parameter getById(Serializable id) {
        Parameter parameter = null;
        List<Parameter> parameters = list();
        for (Parameter para : parameters) {
            if (id.equals(para.getId())) {
                parameter = para;
                break;
            }
        }
        return parameter;
    }

    @Override
    public boolean removeCascadeByIds(Collection<? extends Serializable> idList) {
        List<Parameter> parameters = list();
        for (Parameter parameter : parameters) {
            if (idList.contains(parameter.getId())) {
                FileUtils.deleteFile(Const.DATA_VIEW_PARAMETER_SRC + parameter.getParamKey() + ".json");
            }
        }
        return true;
    }

    @Override
    public Page<Parameter> page(QueryContext context) {
        List<Parameter> parameters = list(context);
        return filePage(context, parameters);
    }

    @Override
    public List<Parameter> list() {
        QueryContext context = new QueryContext();
        return list(context);
    }

    @Override
    public List<Parameter> list(QueryContext context) {
        List<Parameter> parameters = getDTOList(Const.getParamSrc());
        if (context != null && context.getParams() != null) {
            String groupKey = context.getParams().get("groupKey") != null ? context.getParams().get("groupKey").toString() : "";
            String paramKey = context.getParams().get("paramKey") != null ? context.getParams().get("paramKey").toString() : "";
            String name = context.getParams().get("name") != null ? context.getParams().get("name").toString() : "";
            parameters = parameters.stream().filter(parameter -> (StringUtils.isNotBlank(groupKey) ? parameter.getGroupKey().indexOf(groupKey) > -1 : true)
                    && (StringUtils.isNotBlank(paramKey) ? parameter.getParamKey().indexOf(paramKey) > -1 : true)
                    && (StringUtils.isNotBlank(name) ? parameter.getName().indexOf(name) > -1 : true)).collect(Collectors.toList());
        }
        return parameters;
    }

    @Override
    public Parameter getDTO(String fileSrc) {
        Parameter parameter = new Parameter();
        setParameter(parameter, fileSrc);
        if (StringUtils.isBlank(parameter.getParamKey()) || StringUtils.isBlank(parameter.getId())) {
            return null;
        }
        return parameter;
    }

    @Override
    public <Parameter> boolean saveBatch(Class<Parameter> modelClass, Collection<Parameter> entityList, int batchSize) {
        return false;
    }

    @Override
    public boolean saveOrUpdate(Parameter entity) {
        List<Parameter> parameters = list();
        if (entity.getId() == null) {
            entity.setId(StringUtils.getIdStr());
        } else {
            parameters.stream().filter(parameter -> entity.getParamKey().equalsIgnoreCase(parameter.getParamKey())
                    && !entity.getId().equalsIgnoreCase(parameter.getId())).findAny().ifPresent(parameter -> {
                throw new BusinessException("Key已经存在，请重新命名！");
            });
        }
        File path = new File(Const.DATA_VIEW_PARAMETER_SRC);
        if (!path.exists()) {
            path.mkdirs();
        }

        String fileNameWithPath = Const.DATA_VIEW_PARAMETER_SRC + entity.getParamKey() + ".json";

        Parameter parameter = getById(entity.getId());
        if (parameter == null) {
            parameter = new Parameter();
        } else if (!parameter.getParamKey().equalsIgnoreCase(entity.getParamKey())) { //如果CODE发生变化，删除旧的JSON数据
            FileUtils.deleteFile(Const.DATA_VIEW_PARAMETER_SRC + parameter.getParamKey() + ".json");
        }
        com.scs.application.core.utils.BeanUtils.copyProperties(entity, parameter);
        String result = JSON.toJSONString(parameter, SerializerFeature.PrettyFormat);
        FileUtils.writeTxtFile(fileNameWithPath, result);
        return true;
    }

    private void setParameter(Parameter parameter, String fileNameWithPath) {
        String dataViewString = FileUtils.readFileStore(fileNameWithPath);
        if (StringUtils.isEmpty(dataViewString)) {
            return;
        }
        JSONObject jsonObject = JSONObject.parseObject(dataViewString);
        parameter.setParamKey(jsonObject.getString("paramKey"))
                .setName(jsonObject.getString("name"))
                .setGroupKey(jsonObject.getString("groupKey"))
                .setValue(jsonObject.getString("value"))
                .setFileName(jsonObject.getString("fileName"))
                .setFilePath(jsonObject.getString("filePath"))
                .setRemark(jsonObject.getString("remark"))
                .setId(jsonObject.getString("id"));
    }

    @Override
    public Parameter getParameterByKey(String paramKey){
        Parameter parameter = new Parameter();
        setParameter(parameter, Const.getParamSrc() + paramKey + ".json");
        return parameter;
    }

    @Override
    public Boolean isSupport(Boolean flagProject) {
        return !flagProject;
    }
}
